package hr.web.jsf.components;

import hr.web.jsf.components.util.Renderers;

import java.util.List;

import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpServletRequest;

public class UINavigationMenu extends UIComponentBase {
	// By default, getRendersChildren() returns false, so encodeChildren()
	// won't be invoked unless we override getRendersChildren() to return true

	@Override
	public boolean getRendersChildren() {
		return true;
	}

	// The encodeBegin method writes the starting <table> HTML element
	// with the CSS class specified by the <corejsf:tabbedpane>'s styleClass
	// attribute (if supplied)

	@Override
	public void encodeBegin(final FacesContext context)
			throws java.io.IOException {
		final ResponseWriter writer = context.getResponseWriter();
		writer.startElement("div", this);
		writer.writeAttribute("id", getAttributes().get("id"), null);

		final String styleClass = (String) getAttributes().get("styleClass");
		if (styleClass != null) {
			writer.writeAttribute("class", styleClass, null);
		}

		writer.write("\n"); // to make generated HTML easier to read
	}

	// encodeChildren() is invoked by the JSF implementation after
	// encodeBegin().
	// The children of the <corejsf:tabbedpane> component are UISelectItem
	// components, set with one or more <f:selectItem> tags or a single
	// <f:selectItems> tag in the body of <corejsf:tabbedpane>

	@Override
	public void encodeChildren(final FacesContext context)
			throws java.io.IOException {
		// if the tabbedpane component has no children, this method is still
		// called
		if (getChildCount() == 0) {
			return;
		}

		final ResponseWriter writer = context.getResponseWriter();
		writer.startElement("ul", this);

		final List<SelectItem> items = Renderers.getSelectItems(this);
		for (int i = 0; i < items.size(); i++) {
			encodeTab(context, writer, items.get(i));
		}

		writer.endElement("ul");
		writer.write("\n"); // to make generated HTML easier to read
	}

	// encodeEnd() is invoked by the JSF implementation after encodeChildren().
	// encodeEnd() writes the table body and encodes the tabbedpane's content
	// in a single table row.

	// The content for the tabbed pane can be specified as either a URL for
	// a JSP page or a facet name, so encodeEnd() checks to see if it's a facet;
	// if so, it encodes it; if not, it includes the JSP page

	@Override
	public void encodeEnd(final FacesContext context)
			throws java.io.IOException {
		final ResponseWriter writer = context.getResponseWriter();

		// Close off the column, row, and table elements
		writer.endElement("div");
	}

	// encodeTab, which is called by encodeChildren, encodes an HTML anchor
	// element with an onclick attribute which sets the value of the hidden
	// field encoded by encodeHiddenField and submits the tabbedpane's enclosing
	// form. See the decode method for more information about the hidden field.
	// encodeTab also writes out a class attribute for each tab corresponding
	// to either the tabClass attribute (for unselected tabs) or the
	// selectedTabClass attribute (for the selected tab).

	private void encodeTab(final FacesContext context,
			final ResponseWriter writer, final SelectItem item)
			throws java.io.IOException {
		final String tabText = item.getLabel();
		final String content = (String) item.getValue();

		writer.startElement("li", this);
		if (!item.isDisabled()) {
			writer.startElement("a", this);

			writer.writeAttribute("href", content.startsWith("http")
					|| content.startsWith("HTTP") ? content : context
					.getExternalContext().getRequestContextPath()
					+ content, "href");
		}
		final String selectedContent = ((HttpServletRequest) context
				.getExternalContext().getRequest()).getRequestURI();

		String tabClass = null;
		if (selectedContent.contains(content)) {
			tabClass = (String) getAttributes().get("selectedTabClass");
		} else {
			tabClass = (String) getAttributes().get("tabClass");
		}

		if (tabClass != null) {
			writer.writeAttribute("class", tabClass, null);
		}

		writer.write(tabText);
		if (!item.isDisabled()) {
			writer.endElement("a");
		}
		writer.endElement("li");
		writer.write("\n"); // to make generated HTML easier to read
	}

	@Override
	public String getFamily() {
		return "facelets";
	}
}
